<?php
    
namespace App\System\Base\Services;

use App\Exceptions\Customize\ParamsException;
use Omnipay\Omnipay;

class PayService
{
    private $wx_app_id;
    private $wx_mch_id;
    private $wx_api_key;
    private $wx_secret;
    private $wx_notify;
    private $ali_app_id;
    private $ali_private_key;
    private $ali_public_key;
    private $ali_notify;

    public function __construct()
    {
        $config_array = config("pay");
        foreach ($config_array as $k=>$v)
        {
            $this->$k = $v;
        }
        return $this;
    }

    /**
     * 微信支付网关
     * @param  array $orderInfo ['body'=>'描述','out_trade_no'=>'内部订单号',
     * 'total_fee'=>'金额（元）','spbill_create_ip'=>'提交ID（可为空）',
     * 'fee_type'=>'货币类型（可为空）'] 提交参数
     * @param $type 支付网关 1APP支付 2JS支付 3微信H5支付 4微信原生扫码支付 5微信刷卡
     * @return mixed
     */
    public function WxPay(array $orderInfo,$type=1)
    {

        $pay_type = [1=>'WechatPay_App',
                     2=>'WechatPay_Js',
                     3=>'WechatPay_Mweb',
                     4=>'WechatPay_Native',
                     5=>'WechatPay_Pos'];
        if(!isset($pay_type[$type]))
        {
            throw new ParamsException([
                'error_code' => '1000',
                'message'    => '支付网关设置错误',
            ]);
        }
        $type = $pay_type[$type];
        $required_parameter = ['body','out_trade_no','total_fee'];
        foreach ($required_parameter as $v)
        {
            if(!isset($orderInfo[$v]) || !$orderInfo[$v])
            {
                throw new ParamsException([
                    'error_code' => '1000',
                    'message'    => '参数'.$v.'未设置，或为空',
                ]);
            }
            if($v == 'total_fee')
            {
                if(config("app.debug") == true)
                {
                    $orderInfo[$v] =1;//转化成分
                }
                else
                {
                    $orderInfo[$v] = $orderInfo[$v] * 100;//转化成分
                }

            }
        }
        $public_parameter = ['spbill_create_ip'=>$_SERVER['SERVER_ADDR'],'fee_type'=>'CNY'];
        foreach ($public_parameter as $k=>$v)
        {
            if(!isset($orderInfo[$k]) || !$orderInfo[$k])
            {
                $orderInfo[$k] = $v;
            }
        }

        $gateway = Omnipay::create($type);
        $gateway->setAppId($this->wx_app_id);
        $gateway->setMchId($this->wx_mch_id);
        $gateway->setApiKey($this->wx_api_key);
        $gateway->setNotifyUrl($this->wx_notify);
        $request  = $gateway->purchase($orderInfo);
        $response = $request->send();
        if(!$response->isSuccessful())
        {//提交失败，返回错误信息
            //return $response->getData();//要看错误信息可打印此方法
            return false;
        }
        switch ($type){
            case 'WechatPay_App':
                $returnData = $response->getAppOrderData();
                break;
            case 'WechatPay_Js':
                $returnData = $response->getJsOrderData();
                break;
            case 'WechatPay_Native':
                $returnData = $response->getCodeUrl();
                break;
            case 'WechatPay_Pos':
                $returnData = $response->getPosOrderData();
                break;
            case 'WechatPay_Mweb':
                $returnData = $response->getMwebOrderData();
                break;
            default:
                throw new ParamsException([
                    'error_code' => '1000',
                    'message'    => '支付方式错误',
                ]);
                break;

        }

        return $returnData;
    }

    /**
     * 支付宝支付网关
     * @param $type integer 网关类型：1APP支付 2JS支付 3手机网站支付 4PC支付 5当面付
     * @param $orderInfo ['subject'=>'描述','out_trade_no'=>'内部订单号',
     * 'total_amount'=>'金额（元）']
     * @return mixed
     */
    public function AliPay($orderInfo,$type=1)
    {
        $pay_type = [1=>'Alipay_AopApp',
                     2=>'Alipay_AopJs',
                     3=>'Alipay_AopWap',
                     4=>'Alipay_AopPage',
                     5=>'Alipay_AopF2F'];
        if(!isset($pay_type[$type]))
        {
            throw new ParamsException([
                'error_code' => '1000',
                'message'    => '支付网关设置错误',
            ]);
        }
        $type = $pay_type[$type];
        $required_parameter = ['subject','out_trade_no','total_amount'];
        foreach ($required_parameter as $v)
        {
            if(!isset($orderInfo[$v]) || !$orderInfo[$v])
            {
                throw new ParamsException([
                    'error_code' => '1000',
                    'message'    => '参数'.$v.'未设置，或为空',
                ]);
            }
        }
        if(config("app.debug") == true)
        {
            $orderInfo['total_amount'] = '0.01';//转化成分
        }
        $gateway = Omnipay::create($type);
        $gateway->setSignType('RSA2'); //RSA/RSA2
        $gateway->setAppId($this->ali_app_id);
        $gateway->setPrivateKey($this->ali_private_key);
        $gateway->setAlipayPublicKey($this->ali_public_key);
        $gateway->setNotifyUrl($this->ali_notify);
        $gateway->setEnvironment('sandbox');
        $request = $gateway->purchase();
        $request->setBizContent($orderInfo);

        /**
         * @var AopTradeAppPayResponse $response
         */
        $response = $request->send();
        switch ($type){
            case 'Alipay_AopApp':
                $returnData = $response->getOrderString();
                break;
            case 'Alipay_AopJs':
            case 'Alipay_AopWap':
            case 'Alipay_AopPage':
                $returnData = $response->getRedirectUrl();
                break;
            case 'Alipay_AopF2F':
                $returnData = $response->getQrCode();
                break;
            default:
                throw new ParamsException([
                    'error_code' => '1000',
                    'message'    => '支付方式错误',
                ]);
                break;

        }
        return $returnData;

    }
}